// Copyright (c) MatrixFramework. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Matrix.ServiceCommunication.Options;

namespace Matrix.ServiceCommunication.Services;

/// <summary>
/// 基于配置的服务发现提供者
/// </summary>
public class ConfigurationServiceDiscoveryProvider : IServiceDiscoveryProvider
{
    private readonly IOptionsMonitor<ServiceCommunicationOptions> _options;
    private readonly ILogger<ConfigurationServiceDiscoveryProvider> _logger;
    private readonly IMemoryCache _cache;
    private readonly Dictionary<string, List<Uri>> _serviceAddresses;

    public ConfigurationServiceDiscoveryProvider(
        IOptionsMonitor<ServiceCommunicationOptions> options,
        ILogger<ConfigurationServiceDiscoveryProvider> logger,
        IMemoryCache cache)
    {
        _options = options ?? throw new ArgumentNullException(nameof(options));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        _cache = cache ?? throw new ArgumentNullException(nameof(cache));
        _serviceAddresses = new Dictionary<string, List<Uri>>();

        // 从配置中加载服务地址
        LoadServiceAddressesFromConfiguration();
    }

    public Task<Uri> GetServiceAddressAsync(string serviceName, CancellationToken cancellationToken = default)
    {
        var addresses = GetServiceAddressesAsync(serviceName, cancellationToken);
        var addressList = addresses.Result;

        if (!addressList.Any())
        {
            throw new InvalidOperationException($"服务 '{serviceName}' 未找到可用的地址");
        }

        // 简单的轮询负载均衡
        var cacheKey = $"service_round_robin:{serviceName}";
        var index = _cache.GetOrCreate(cacheKey, _ => 0) % addressList.Count;
        _cache.Set(cacheKey, index + 1);

        var selectedAddress = addressList[index];
        _logger.LogDebug("选择服务地址: {ServiceName} -> {Address} (索引: {Index})",
            serviceName, selectedAddress, index);

        return Task.FromResult(selectedAddress);
    }

    public Task<IReadOnlyList<Uri>> GetServiceAddressesAsync(string serviceName, CancellationToken cancellationToken = default)
    {
        if (_serviceAddresses.TryGetValue(serviceName, out var addresses))
        {
            return Task.FromResult<IReadOnlyList<Uri>>(addresses);
        }

        _logger.LogWarning("服务 '{ServiceName}' 未配置地址", serviceName);
        return Task.FromResult<IReadOnlyList<Uri>>(new List<Uri>());
    }

    public Task RegisterServiceAsync(ServiceRegistration serviceRegistration, CancellationToken cancellationToken = default)
    {
        _logger.LogWarning("配置驱动的服务发现不支持动态注册服务: {ServiceName}",
            serviceRegistration.ServiceName);
        return Task.CompletedTask;
    }

    public Task UnregisterServiceAsync(string serviceName, string serviceId, CancellationToken cancellationToken = default)
    {
        _logger.LogWarning("配置驱动的服务发现不支持动态注销服务: {ServiceName}", serviceName);
        return Task.CompletedTask;
    }

    public Task<IReadOnlyList<ServiceInfo>> GetServicesAsync(CancellationToken cancellationToken = default)
    {
        var services = _serviceAddresses.Select(kvp => new ServiceInfo
        {
            ServiceName = kvp.Key,
            Instances = kvp.Value.Select((address, index) => new ServiceInstance
            {
                ServiceId = $"{kvp.Key}-{index}",
                Address = address,
                Port = address.Port,
                Enabled = true,
                Healthy = true,
                RegisteredAt = DateTime.UtcNow,
                LastHeartbeat = DateTime.UtcNow
            }).ToList()
        }).ToList();

        return Task.FromResult<IReadOnlyList<ServiceInfo>>(services);
    }

    private void LoadServiceAddressesFromConfiguration()
    {
        // 这里可以从配置文件中读取服务地址映射
        // 示例配置结构：
        // "ServiceDiscovery": {
        //   "Services": {
        //     "AuthService": [ "http://localhost:5001", "http://localhost:5002" ],
        //     "UserService": [ "http://localhost:5003" ],
        //     "ConfigService": [ "http://localhost:5004" ]
        //   }
        // }

        // 预定义一些基础服务地址
        AddServiceAddress("AuthService", new Uri("http://localhost:5001"));
        AddServiceAddress("UserService", new Uri("http://localhost:5002"));
        AddServiceAddress("TenantService", new Uri("http://localhost:5003"));
        AddServiceAddress("ConfigService", new Uri("http://localhost:5004"));
        AddServiceAddress("NotificationService", new Uri("http://localhost:5005"));
        AddServiceAddress("FileStorageService", new Uri("http://localhost:5006"));
        AddServiceAddress("KeycloakService", new Uri("http://localhost:8080"));

        _logger.LogInformation("已加载 {Count} 个服务的地址配置", _serviceAddresses.Count);
    }

    private void AddServiceAddress(string serviceName, params Uri[] addresses)
    {
        if (!_serviceAddresses.ContainsKey(serviceName))
        {
            _serviceAddresses[serviceName] = new List<Uri>();
        }

        _serviceAddresses[serviceName].AddRange(addresses);
        _logger.LogDebug("添加服务地址: {ServiceName} -> {Addresses}",
            serviceName, string.Join(", ", addresses.Select(a => a.ToString())));
    }
}